package com.berchen.Optional;

import com.berchen.Lambda表达式.Employee;
import org.junit.Test;

import java.util.Optional;

/**
 * Optional<T> 类：是一个容器类，代表一个值存在或不存在，原来用null表示一个值不存在，现在用Optional可以更好的表达这个概念，并且可以避免空指针异常。
 *
 * 常用方法：
 *  Optional.of(T t)：创建一个Optional实例。T不能为null，否则会报空指针异常（上面说不会出现空指针异常，这里出现空指针异常可以快速定位到代码是什么地方出现了空指针异常 ）。
 *  Optional.empty()：创建一个空的Optional实例
 *  Optional.ofNullable(T t)：若t不为null，创建Optional实例，否则创建空实例。
 *  isPresent():判断Optional中是否包含值。
 *  orElse(T t):如果Optional中包含值，返回该值，否则返回t。
 *  orElseGet(Supplier s):如果Optional中包含值，返回该值，否则返回s获取的值。
 *  map(Function f):如果Optional中有值就对值进行处理，并返回处理后的Optional，否则返回Optional.empty()。
 *  flatMap(Function mapper):与map相似，要求返回值必须是Optional。
 *  get()：获取容器中的对象。
 */
public class TestOptional {

    @Test
    public void test1(){

        // of of方法不能为null。
        Optional<Employee> employee = Optional.of(new Employee());  // 创建一个Optional实例
        System.out.println(employee.get());

        // empty 构建一个空实例，不能get，get会出现空指针异常
        Optional<Employee> empty = Optional.empty();
//        System.out.println(empty.get());

        // ofNullable 参数为null就构建空的，如果不为null，就构建实例
        Optional<Employee> employee1 = Optional.ofNullable(new Employee());
        Optional<Employee> employee2 = Optional.ofNullable(null);
//        System.out.println(employee2.get());  // employee2 是空实例，所以get会报错

        // isPresent 判断Optional中是否有值,有值返回true，没有值返回false
        if(!employee2.isPresent()){
            System.out.println("Optional为空");
        }

        // orElse 调用是否有值，如果有就返回，如果没有就返回参数这个
        Employee employee3 = employee2.orElse(new Employee("chen", 12, 33.3, Employee.Status.VOCATION));
        System.out.println(employee3);

        // orElseGet 和orElse类似，只不过如果为空返回的是Supplier
        Employee employee4 = employee2.orElseGet(Employee::new);

        // map 有值对值进行处理，没有值返回 Optional.empty 这是一个字符串
        Optional<String> s = employee2.map(x -> x.getName().toUpperCase());
        System.out.println(s);

        // flatMap 与map类似 但是必须返回Optional
        Optional<String> s1 = employee2.flatMap(x -> Optional.of(x.getName().toUpperCase()));
    }
}
